feat(postgres-config): operator-owned postgresql.conf per shard - #554
Merged
GuptaManan100 merged 1 commit intoAug 6, 2026
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
GuptaManan100
marked this pull request as ready for review
August 4, 2026 11:04
GuptaManan100
force-pushed
the
manangupta/mul-1157-operator-changes-to-support-postgres-config-propogation
branch
from
August 6, 2026 05:12
de8de5f to
d1e198d
Compare
This comment has been minimized.
This comment has been minimized.
…hard Render and manage an operator-owned postgresql.conf for each shard, scaling defaults from shard resources and rendering a per-shard cluster_name. Add an inline spec.postgresConfig map (deprecating the ConfigMap ref), validate GUCs at admission, reject managed GUCs, and gate rollout on config health. Report rollout state in shard status based on effective config content rather than generation, and cover the behavior with an end-to-end suite verifying effective GUCs. Signed-off-by: GuptaManan100 <guptamanan100@gmail.com>
GuptaManan100
force-pushed
the
manangupta/mul-1157-operator-changes-to-support-postgres-config-propogation
branch
from
August 6, 2026 05:30
d1e198d to
da951ab
Compare
GuptaManan100
enabled auto-merge (squash)
August 6, 2026 05:31
GuptaManan100
disabled auto-merge
August 6, 2026 05:32
🔬 Go Test Coverage ReportSummary
Status✅ PASS DetailShow New Coverage |
GuptaManan100
deleted the
manangupta/mul-1157-operator-changes-to-support-postgres-config-propogation
branch
August 6, 2026 05:36
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Make the operator own each shard's PostgreSQL configuration (
postgresql.conf), rendered as a layered config into an operator-owned ConfigMap and rolled out through the existing primary-last restart. Precedence, lowest → highest:postgresql.conftemplate the operator owns end-to-end (SSL, locales, logging,wal_level = logical, and conservative small-instance defaults).shared_buffers = mem/4,effective_cache_size,work_mem,max_parallel_workers*, …) plus disk-based WAL sizing (max_wal_size,wal_keep_size, …).postgresConfigRef— the existing ConfigMap-ref content, now deprecated in favor of the inline map.spec.postgresConfig— a user-suppliedmap[string]stringof GUC overrides, the intended long-term surface.The result is written to an operator-owned
<shard>-postgres-configConfigMap and mounted into thepostgressidecar viaPOSTGRES_INITDB_EXTRA_CONF. A content hash of the rendered config drives the existing drain → primary-last restart state machine, so config changes roll out the same way resource changes already do.Config is shard-level, not per-pool: every pool in a shard gets identical config, which keeps primaries and replicas uniform across failover. Where sizing needs a single basis, per-pool resources are reduced to the shard — max(memory, CPU) across pools (so replication-sensitive settings stay valid on every pod) and min(disk) (so WAL budgeting never overfills the smallest volume).
cluster_nameis rendered from the cluster/database/tablegroup/shard identity sops/log output distinguishes shards.Validation (admission)
spec.postgresConfigGUCs are validated at admission against a 382-entry catalog generated from PostgreSQL'sguc_tables.c(REL_17_5): unknown parameter names and gross type mismatches are rejected. Additionally, operator-managed GUCs are rejected rather than silently ignored:port,listen_addresses,unix_socket_directories,data_directory,hba_file,ident_file), so a config-file value would be a no-op;wal_levelmust staylogicalfor multigres replication.Status
status.postgresConfigreports rollout state so callers can poll without inspecting pods:{ inProgress, lastAppliedAt, error }.inProgressis content-based — it compares the config effective on the pods against the desired render, so it correctly reflects apostgresConfigRefConfigMap edit or a new operator baseline on upgrade, neither of which bumps the shardgeneration. (Freshness for a spec change is the shard's top-levelstatus.observedGeneration.)Testing
TestPostgresConfigManagement(e2e, kind) brings up a sized cluster with an inline map and a legacy ref, then asserts effective values viaSHOW <param>through the gateway: baselinewal_level=logical,shared_buffers=128MB(from a 512Mi limit), inlinemax_connections=150, map-over-refwork_mem=16MB, ref-honoredrandom_page_cost=2.5, and the per-shard ConfigMap.Dependency / known limitation
Applying config changes to an already-running cluster depends on an upstream pgctld change. Today pgctld reads
POSTGRES_INITDB_EXTRA_CONFonly at initdb, so:include_if_exists). The e2e subtestchanging spec.postgresConfig takes effect on the running clusteris present and will pass once that lands; the managed-GUC and apply-health guardrails above also become fully active then.Follow-up (separate PR)
Reload vs. restart classification is intentionally out of scope here and will be a separate PR. Today every config change takes the full rolling-restart path. The follow-up will classify changed GUCs by
pg_settings.contextand applysighup-context changes via a verified reload (no pod restart), falling back to restart otherwise. It needs the observability half to confirm a reload actually took effect (a verifying pgctld reload RPC, or an operator-side check) — this PR deliberately makes the status signal content-based and observation-driven so that reload path plugs into the same "effective == desired" loop without an API change.